#include "I2CInitHelper.h"
#include "BaseDef.h"
#include "BoardCommunicationModule.h"
#include "BufDef.h"

/** \brief RTC中断
*
*/
/* INT_SRC_TMR2_1_CMP_A Callback. */

/*= 外部RTC中断 =*/

// 外部RTC输入中断1
void INT_SRC_PORT_EIRQ8_IrqCallback(void) {
  rt_kprintf("get a rtc sec invc!\n");
}

// I2C4错误或者事件中断。用来处理RTC通信错误
void I2C4_EE_IrqHandler(void) {
  /* If starf flag valid */
    if (SET == I2C_GetStatus(CM_I2C4, I2C_FLAG_START)) {
        I2C_ClearStatus(CM_I2C4, I2C_CLR_STARTFCLR | I2C_CLR_NACKFCLR);
        I2C_IntCmd(CM_I2C4, I2C_INT_STOP | I2C_INT_NACK, ENABLE);

		// 区分读数据和写数据
        if (i2c_4_rx_app_buf.transport_mode == MD_Write) {
            /* Enable TEI interrupt which indicate address transfer end */
            I2C_IntCmd(CM_I2C4, I2C_INT_TX_CPLT, ENABLE);

            I2C_WriteData(CM_I2C4, i2c_4_rx_app_buf.data_buf[0] + 1);
        } else {
            /* if read data length is 1 */
            if (i2c_4_rx_app_buf.receive_data_len == 1U) {
                I2C_AckConfig(CM_I2C4, I2C_NACK);
            }

            /* Enable RXI interrupt which indicate data receive buffer full */
            I2C_IntCmd(CM_I2C4, I2C_INT_RX_FULL, ENABLE);

            I2C_WriteData(CM_I2C4, i2c_4_rx_app_buf.data_buf[0]);
        }
    }

    /* If NACK interrupt occurred */
    if (SET == I2C_GetStatus(CM_I2C4, I2C_FLAG_NACKF)) {
        /* clear NACK flag*/
        I2C_ClearStatus(CM_I2C4, I2C_CLR_NACKFCLR);
        /* Stop tx or rx process*/
        I2C_IntCmd(CM_I2C4, I2C_INT_TX_EMPTY | I2C_INT_RX_FULL | I2C_INT_TX_CPLT | I2C_INT_NACK, DISABLE);

        /* Generate stop condition */
        I2C_GenerateStop(CM_I2C4);
    }

    if (SET == I2C_GetStatus(CM_I2C4, I2C_FLAG_STOP)) {
        /* Disable Stop flag interrupt */
        I2C_IntCmd(CM_I2C4, I2C_INT_TX_EMPTY | I2C_INT_RX_FULL | I2C_INT_TX_CPLT | I2C_INT_STOP | I2C_INT_NACK, \
                   DISABLE);
        I2C_ClearStatus(CM_I2C4, I2C_CLR_STOPFCLR);
        I2C_Cmd(CM_I2C4, DISABLE);

        /* Communication finished */
        i2c_4_rx_app_buf.port_status = I2C_PORT_IDLE;
    }
}

/* INT_SRC_I2C4_TXI Callback. I2C4 接收中断 外部RTC、温湿度传感器 */
void INT_SRC_I2C4_TXI_IrqCallback(void) {

  //add your codes here
	if (i2c_4_rx_app_buf.send_translate_index <= (i2c_4_rx_app_buf.send_data_len - 1U)) {
        I2C_WriteData(CM_I2C4, i2c_4_rx_app_buf.data_buf[i2c_4_rx_app_buf.send_translate_index]);
        i2c_4_rx_app_buf.send_translate_index++;
    } else {
        I2C_IntCmd(CM_I2C4, I2C_INT_TX_EMPTY, DISABLE);
        I2C_IntCmd(CM_I2C4, I2C_INT_TX_CPLT, ENABLE);
    }
}
/* INT_SRC_I2C4_RXI Callback. I2C4 发送中断 外部RTC、温湿度传感器 */
void INT_SRC_I2C4_RXI_IrqCallback(void) {
  //add your codes here
	// 检查发送长度。具体查看ACK收发规则
	// 这里要加上发送缓冲区是因为发送缓冲区在它前面
  if ((i2c_4_rx_app_buf.receive_data_len >= 2U) 
		&& (i2c_4_rx_app_buf.receive_translate_index == (i2c_4_rx_app_buf.receive_data_len + i2c_4_rx_app_buf.send_data_len - 2U))) {
    I2C_AckConfig(CM_I2C4, I2C_NACK);
  }

  if (i2c_4_rx_app_buf.receive_translate_index == (i2c_4_rx_app_buf.receive_data_len + i2c_4_rx_app_buf.send_data_len - 1U)) {
    /* Enable Stop flag interrupt */
    I2C_IntCmd(CM_I2C4, I2C_INT_STOP, ENABLE);
    /* Disable RXI interrupt */
    I2C_IntCmd(CM_I2C4, I2C_INT_RX_FULL, DISABLE);
    /* Generate stop condition */
    I2C_GenerateStop(CM_I2C4);

    I2C_AckConfig(CM_I2C4, I2C_ACK);
  }
  
  if (i2c_4_rx_app_buf.receive_translate_index >= i2c_4_rx_app_buf.receive_data_len + i2c_4_rx_app_buf.send_data_len) {
    // 出错了，发送长度不正确。
    Reset_I2c_Data_Task_Obj(&i2c_4_rx_app_buf);
    rt_kprintf("i2c4 receive error\n");
  }
	i2c_4_rx_app_buf.data_buf[i2c_4_rx_app_buf.receive_translate_index] = I2C_ReadData(CM_I2C4);
	i2c_4_rx_app_buf.receive_translate_index++;
}

/* INT_SRC_I2C4_RXI Callback. I2C4 发送完成中断 外部RTC、温湿度传感器 */
void INT_SRC_I2C4_TEI_IrqCallback(void) {
  I2C_IntCmd(CM_I2C4, I2C_INT_TX_CPLT, DISABLE);

  if (i2c_4_rx_app_buf.send_translate_index == 0U) {
    /* Indicate address send finished */
    if (SET == I2C_GetStatus(CM_I2C4, I2C_FLAG_TRA)) {
      /* If Address send receive ACK */
      if (RESET == I2C_GetStatus(CM_I2C4, I2C_FLAG_NACKF)) {
        /* Config tx buffer empty interrupt function*/
        I2C_IntCmd(CM_I2C4, I2C_INT_TX_EMPTY, ENABLE);
        /* Need transfer first data here */
        if (i2c_4_rx_app_buf.send_translate_index >= i2c_4_rx_app_buf.send_data_len) {
          // 出错了，发送长度不正确。
          Reset_I2c_Data_Task_Obj(&i2c_4_rx_app_buf);
          rt_kprintf("i2c4 send error\n");
        }
        I2C_WriteData(CM_I2C4, i2c_4_rx_app_buf.data_buf[i2c_4_rx_app_buf.send_translate_index]);
        i2c_4_rx_app_buf.send_translate_index++;
      } else {
        I2C_IntCmd(CM_I2C4, I2C_INT_NACK, DISABLE);
        /* Generate stop if receive NACK */
        I2C_IntCmd(CM_I2C4, I2C_INT_STOP, ENABLE);
        /* Generate stop condition */
        I2C_GenerateStop(CM_I2C4);
      }
    }
  } else {
    /* Data Send finish */
    I2C_IntCmd(CM_I2C4, I2C_INT_STOP, ENABLE);
    /* Generate stop condition */
    I2C_GenerateStop(CM_I2C4);
  }
}

/* 外部RTC中断 */

//I2Cx Config
void App_I2CxCfg(void) {
  int32_t i32Ret;
  stc_i2c_init_t stcI2cInit;
  float32_t fErr;

  /* Enable I2C2 clock */
  FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_I2C2, ENABLE);
  /************************* Configure I2C2***************************/
  I2C_DeInit(CM_I2C2);

  (void) I2C_StructInit(&stcI2cInit);
  stcI2cInit.u32ClockDiv = I2C_CLK_DIV1;
  stcI2cInit.u32Baudrate = 400000UL;
  stcI2cInit.u32SclTime = 0UL;
  i32Ret = I2C_Init(CM_I2C2, &stcI2cInit, &fErr);
  if (LL_OK != i32Ret) {
    //Initialized failed, add your code here.
    GPIO_SetPins(LED_RUN_PORT, LED_RUN_PIN);
    for (;;) {
    }
  }
  I2C_BusWaitCmd(CM_I2C2, ENABLE);


  /* Enable interrupt function*/
  I2C_IntCmd(CM_I2C2, I2C_INT_RX_FULL | I2C_INT_TX_EMPTY | I2C_INT_TMOUTIE, ENABLE);

  /* Enable I2C4 clock */
  FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_I2C4, ENABLE);
  /************************* Configure I2C4***************************/
  I2C_DeInit(CM_I2C4);

  (void) I2C_StructInit(&stcI2cInit);
  stcI2cInit.u32ClockDiv = I2C_CLK_DIV1;
  stcI2cInit.u32Baudrate = 400000UL;
  stcI2cInit.u32SclTime = 0UL;
  i32Ret = I2C_Init(CM_I2C4, &stcI2cInit, &fErr);
  if (LL_OK != i32Ret) {
    //Initialized failed, add your code here.
    GPIO_SetPins(LED_RUN_PORT, LED_RUN_PIN);
    for (;;) {
    }
  }
  I2C_BusWaitCmd(CM_I2C4, ENABLE);


  /* Enable interrupt function*/
  I2C_IntCmd(CM_I2C4, I2C_INT_RX_FULL | I2C_INT_TX_EMPTY | I2C_INT_TMOUTIE, ENABLE);
}
